package blog.controller.admin;


import blog.entity.Blog;
import blog.entity.BlogTag;
import blog.entity.Tag;
import blog.service.BlogService;
import blog.service.BlogTagService;
import blog.service.TagService;
import blog.util.BlogUtils;
import blog.util.Result;
import blog.util.ResultGenerator;
import blog.util.TimeUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author StarryX
 * @since 2020-10-01
 */
@Controller
@RequestMapping("/admin")
public class BlogController {
    @Autowired
    private BlogService blogService;

    @Autowired
    private TagService tagService;

    @Autowired
    private BlogTagService blogTagService;

    @GetMapping("/blogs/list")
    @ResponseBody
    //分页展示博客列表，返回的是json
    public Result list(@RequestParam Map<String, Object> params) {
        /**
         * params ：
         *  page：表示请求页码的参数名称
         *  limit：表示请求行数的参数名称
         */
        if (StringUtils.isEmpty(params.get("page")) || StringUtils.isEmpty(params.get("limit"))) {
            return ResultGenerator.genFailResult("参数异常！");
        }
        //这里可以用 Page对象的方法获取所需要的值（数组集合，当前页数，总页数，总行数），将其封装到一个Map对象中，传回前端
        Page<Blog> page = new Page<>(Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("limit").toString()));
        if (params.get("page").toString().equals("asc")) {       //查询出的分页按升序排序
            blogService.page(page, new QueryWrapper<Blog>()
                    .orderByAsc(StringUtils.isEmpty(params.get("sidx")) ? "update_time" : params.get("sidx").toString()));     //todo： 记得修改前端页面js中的 index 属性，将改为与数据库表中字段一致
        } else {                                                  //查询出的分页按降序排序
            blogService.page(page, new QueryWrapper<Blog>()
                    .orderByDesc(StringUtils.isEmpty(params.get("sidx")) ? "update_time" : params.get("sidx").toString()));
        }
        //todo: 这里搜索功能删除了，记得在前端删除对应的代码
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("list", page.getRecords());
        resultMap.put("currPage", page.getCurrent());
        resultMap.put("totalPage", page.getPages());
        resultMap.put("totalCount", page.getTotal());
        return ResultGenerator.genSuccessResult(resultMap);
    }


    @GetMapping("/blogs")
    public String list(HttpServletRequest request) {
        request.setAttribute("path", "blogs");
        return "admin/blog";
    }

    @GetMapping("/blogs/edit")
    public String edit(HttpServletRequest request) {
        request.setAttribute("path", "edit");   //点亮对应的侧边栏
        //todo: 这里删除了分类的模块，记得在页面上删除对应代码
        return "admin/edit";
    }

    @GetMapping("/blogs/edit/{blogId}")
    public String edit(HttpServletRequest request, @PathVariable("blogId") Integer blogId) {
        request.setAttribute("path", "edit");   //点亮对应的侧边栏
        Blog blog = blogService.getById(blogId);
        if (blog == null) {
            return "error/error_400";
        }
        request.setAttribute("blog", blog);
        //todo: 这里删除了分类的模块，记得在页面上删除对应代码
        return "admin/edit";
    }

    @PostMapping("/blogs/save")
    @ResponseBody
    public Result save(@RequestParam("blogTitle") String blogTitle,
                       @RequestParam("blogTags") String blogTags,
                       @RequestParam("blogContent") String blogContent) {
        if (StringUtils.isEmpty(blogTitle)) {
            return ResultGenerator.genFailResult("请输入文章标题");
        }
        if (blogTitle.trim().length() > 150) {
            return ResultGenerator.genFailResult("标题过长");
        }
        if (StringUtils.isEmpty(blogTags)) {
            return ResultGenerator.genFailResult("请输入文章标签");
        }
        String[] tags = blogTags.split(",");
        if (blogTags.trim().length() > 150) {
            if (tags.length > 6) {
                return ResultGenerator.genFailResult("标签数量限制为6");
            }
            return ResultGenerator.genFailResult("标签过长");
        }
        if (StringUtils.isEmpty(blogContent)) {
            return ResultGenerator.genFailResult("请输入文章内容");
        }
        Blog checkBlog = blogService.getOne(new QueryWrapper<Blog>().eq("title", blogTitle));
        if (checkBlog != null){
            return ResultGenerator.genFailResult("标题已存在");
        }
        Blog blog = new Blog();
        blog.setTitle(blogTitle);
        blog.setTag(blogTags);
        blog.setContent(blogContent);
        blog.setCreateTime(TimeUtils.getTime());
        blog.setUpdateTime(TimeUtils.getTime());
        boolean saveBlogResult = blogService.save(blog);     //返回 成功 或 失败 的字符串
        //在此处关联博客和标签
        //新增的tag对象
        List<Tag> tagListForInsert = new ArrayList<>();
        //所有的tag对象，用于建立关系数据
        List<Tag> allTagsList = new ArrayList<>();
        for (int i = 0; i < tags.length; i++) {
            Tag tag = tagService.getOne(new QueryWrapper<Tag>().eq("tag_name", tags[i]));
            if (tag == null) {
                //不存在就新增
                Tag tempTag = new Tag();
                tempTag.setTagName(tags[i]);
                tempTag.setUpdateTime(TimeUtils.getTime());
                tempTag.setCreateTime(TimeUtils.getTime());
                tagListForInsert.add(tempTag);
            } else {
                allTagsList.add(tag);
            }
        }
        //新增标签数据并修改分类排序值
        if (!CollectionUtils.isEmpty(tagListForInsert)) {
            tagService.saveBatch(tagListForInsert);
        }
        allTagsList.addAll(tagListForInsert);
        List<BlogTag> blogTagRelations = new ArrayList<>();

        //新增关系数据
        for (Tag tag : allTagsList) {
            BlogTag blogTag = new BlogTag();
            blogTag.setBlogId(blog.getId());
            blogTag.setTagId(tag.getId());
            blogTag.setCreateTime(TimeUtils.getTime());
            blogTag.setUpdateTime(TimeUtils.getTime());
            blogTagRelations.add(blogTag);
        }
        boolean saveBlogTagResult = blogTagService.saveBatch(blogTagRelations);
        if (saveBlogResult && saveBlogTagResult) {
            return ResultGenerator.genSuccessResult("成功");
        } else {
            return ResultGenerator.genFailResult("失败");
        }
    }

    @PostMapping("/blogs/update")
    @ResponseBody
    public Result update(@RequestParam("blogId") Integer blogId,
                         @RequestParam("blogTitle") String blogTitle,
                         @RequestParam("blogTags") String blogTags,
                         @RequestParam("blogContent") String blogContent) {
        if (StringUtils.isEmpty(blogTitle)) {
            return ResultGenerator.genFailResult("请输入文章标题");
        }
        if (blogTitle.trim().length() > 150) {
            return ResultGenerator.genFailResult("标题过长");
        }
        if (StringUtils.isEmpty(blogTags)) {
            return ResultGenerator.genFailResult("请输入文章标签");
        }
        String[] tags = blogTags.split(",");
        if (blogTags.trim().length() > 150) {
            if (tags.length > 6) {
                return ResultGenerator.genFailResult("标签数量限制为6");
            }
            return ResultGenerator.genFailResult("标签过长");
        }
        if (StringUtils.isEmpty(blogContent)) {
            return ResultGenerator.genFailResult("请输入文章内容");
        }
        Blog blog = new Blog();
        blog.setId(blogId);
        blog.setTitle(blogTitle);
        blog.setTag(blogTags);
        blog.setContent(blogContent);
        blog.setUpdateTime(TimeUtils.getTime());
        boolean updateBlogResult = blogService.updateById(blog);
        //这里更新关联博客标签
        //新增的tag对象
        List<Tag> tagListForInsert = new ArrayList<>();
        //所有的tag对象，用于建立关系数据
        List<Tag> allTagsList = new ArrayList<>();
        for (int i = 0; i < tags.length; i++) {
            Tag tag = tagService.getOne(new QueryWrapper<Tag>().eq("tag_name", tags[i]));
            if (tag == null) {
                //不存在就新增
                Tag tempTag = new Tag();
                tempTag.setTagName(tags[i]);
                tempTag.setUpdateTime(TimeUtils.getTime());
                tempTag.setCreateTime(TimeUtils.getTime());
                tagListForInsert.add(tempTag);
            } else {
                allTagsList.add(tag);
            }
        }
        //新增标签数据并修改分类排序值
        if (!CollectionUtils.isEmpty(tagListForInsert)) {
            tagService.saveBatch(tagListForInsert);
        }
        allTagsList.addAll(tagListForInsert);
        //先删除原来的博客与标签中间表的相关数据，在插入新的关系
        blogTagService.remove(new QueryWrapper<BlogTag>().eq("blog_id", blog.getId()));
        List<BlogTag> blogTagRelations = new ArrayList<>();
        //新增关系数据
        for (Tag tag : allTagsList) {
            BlogTag blogTag = new BlogTag();
            blogTag.setBlogId(blog.getId());
            blogTag.setTagId(tagService.getOne(new QueryWrapper<Tag>().eq("tag_name", tag.getTagName())).getId());
            blogTag.setCreateTime(TimeUtils.getTime());
            blogTag.setUpdateTime(TimeUtils.getTime());
            blogTagRelations.add(blogTag);
        }
        boolean saveBlogTagResult = blogTagService.saveBatch(blogTagRelations);
        if (updateBlogResult) {
            return ResultGenerator.genSuccessResult("修改成功");
        } else {
            return ResultGenerator.genFailResult("修改失败");
        }
    }

    @PostMapping("/blogs/md/uploadfile")
    public void uploadFileByEditormd(HttpServletRequest request,
                                     HttpServletResponse response,
                                     @RequestParam(name = "editormd-image-file", required = true)
                                             MultipartFile file) throws IOException, URISyntaxException {
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //生成文件名称通用方法
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        Random r = new Random();
        StringBuilder tempName = new StringBuilder();
        tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
        String newFileName = tempName.toString();
        //创建文件
        File destFile = new File(System.getProperty("user.dir") + "/upload/" + newFileName);
        String fileUrl = BlogUtils.getHost(new URI(request.getRequestURL() + "")) + "/upload/" + newFileName;
        File fileDirectory = new File(System.getProperty("user.dir") + "/upload/");
        try {
            if (!fileDirectory.exists()) {
                if (!fileDirectory.mkdir()) {
                    throw new IOException("文件夹创建失败,路径为：" + fileDirectory);
                }
            }
            file.transferTo(destFile);
            request.setCharacterEncoding("utf-8");
            response.setHeader("Content-Type", "text/html");
            response.getWriter().write("{\"success\": 1, \"message\":\"success\",\"url\":\"" + fileUrl + "\"}");
        } catch (UnsupportedEncodingException e) {
            response.getWriter().write("{\"success\":0}");
        } catch (IOException e) {
            response.getWriter().write("{\"success\":0}");
        }
    }

    @PostMapping("/blogs/delete")
    @ResponseBody
    public Result delete(@RequestBody Integer[] ids) {
        if (ids.length < 1) {
            return ResultGenerator.genFailResult("参数异常！");
        }
        if (blogService.removeByIds(Arrays.asList(ids))) {
            return ResultGenerator.genSuccessResult();
        } else {
            return ResultGenerator.genFailResult("删除失败");
        }
    }
}

